Loadbalancer
로드밸런서는 서버에 가해지는 부하를 분산해주는 기술 및 장치로 클라이언트와 서버 사이에 위치하여 한 대의 서버로 부하가 집중되지 않도록 트래픽을 관리해 각각의 서버가 최적의 성능을 내도록 한다.
쿠버네티스에서도 로드밸런서를 사용 가능하며 이전 포스트의 NodePort 방식과 같은 경우 클라이언트의 요청을 모두 워커 노드의 노드포트를 통해 노드포트 서비스로 이동하고 이를 다시 각 파드로 보내는 방식이기 때문에 비효율적이라고 볼수 있다.
하지만 로드밸런서를 사용한다면 다음과 같은 구조로 간단하게 외부에 노출하고 부하를 분산할 수 있다.
하지만 로드밸런서를 사용하기 위해서는 쿠버네티스를 클라우드 환경에 구축하고 해당 클라우드에서 제공하는 로드밸런서(ELB ..)를 사용하여 클러스터 외부에 구현해주어야 한다.
MetalLB
현재 로컬에 온프레미스 환경으로 클러스터를 구축했기 때문에 외부에서 제공받을 로드밸런스가 따로 존재하지 않는다.
하지만 온프레미스에서도 로드밸런서를 사용할 수 있도록 고안된 프로젝트인 metalLB를 사용하면 로컬의 온프레미스 환경에서도 로드밸런서 구축이 가능하다.
MetalLB는 특별한 네트워크 설정이나 구성이 있는 것이 아니라 기존의 L2/L3 네트워크로 로드밸런서를 구현하기 때문에 새로 배워야 할 부담이 적고 연동이 매우 쉽다는 장점이 있다.
실습
실습으로 MetalLB의 L2 네트워크로 로드밸런서를 구현하고 아래와 같이 두 개의 MetalbLB 로드밸런서 서비스를 구현한다.
사용자가 로드밸런서 서비스에 접근하면 서비스에서 파드로 포워딩 해주는 구조이다.
아래 작업을 따라해보자.
1. 디플로이먼트를 이용해 2종류(lb-hname-pods,lb-ip-pods)의 파드를 생성하자. 그리고 scale 명령으로 파드를 2개로 늘려 노드당 1개씩 파드가 배포되도록 하자
$ kubectl create deployment lb-hname-pods --image=sysnet4admin/echo-hname
$ kubectl scale deployment/lb-hname-pods --replicas=2
$ kubectl create deployment lb-ip-pods --image=sysnet4admin/echo-ip
$ kubectl scale deployment/lb-ip-pods --replicas=2
2. 2종류의 파드가 2개씩 총 4개가 배포되었는지 확인
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
lb-hname-pods-79b95c7c7b-rd799 1/1 Running 0 90s 172.16.103.145 w2-k8s <none> <none>
lb-hname-pods-79b95c7c7b-sdclw 1/1 Running 0 81s 172.16.221.186 w1-k8s <none> <none>
lb-ip-pods-6c6bb59b4-8jlxz 1/1 Running 0 38s 172.16.103.146 w2-k8s <none> <none>
lb-ip-pods-6c6bb59b4-xm9d2 1/1 Running 0 33s 172.16.221.187 w1-k8s <none> <none>
3. 인그레스와 마찬가지로 사전에 정의된 오브젝트 스펙으로 MetalLB를 구성한다.
$ kubectl apply -f ~/_Book_k8sInfra/ch3/3.3.4/metallb.yaml
namespace/metallb-system created
podsecuritypolicy.policy/speaker created
serviceaccount/controller created
serviceaccount/speaker created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
role.rbac.authorization.k8s.io/config-watcher created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/config-watcher created
daemonset.apps/speaker created
deployment.apps/controller created
4. 배포된 metalLB의 파드가 5개(Controller 1개, speaker 4개)인지 확인하고 IP와 상태도 확인
$ kubectl get pods -n metallb-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
controller-5d48db7f99-9g2t6 1/1 Running 0 52s 172.16.221.188 w1-k8s <none> <none>
speaker-2ptq8 1/1 Running 0 52s 192.168.1.101 w1-k8s <none> <none>
speaker-l6p5h 1/1 Running 0 52s 192.168.1.10 m-k8s <none> <none>
speaker-mplg6 1/1 Running 0 52s 192.168.1.102 w2-k8s <none> <none>
5. 인그레스와 마찬가지로 MetalLB도 설정을 적용해야 한다. 이 때 오브젝트는 ConfigMap을 사용함. ConfigMap은 설정이 정의된 포맷이라고 생각하면 된다.
$ kubectl apply -f ~/_Book_k8sInfra/ch3/3.3.4/metallb-l2config.yaml
configmap/config created
파일 구성은 아래와 같다
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: nginx-ip-range
protocol: layer2
addresses:
- 192.168.1.11-192.168.1.13
6. ConfigMap이 생성되었는지 확인
$ kubectl get configmap -n metallb-system
NAME DATA AGE
config 1 71s
7. -o yaml 옵션을 주고 다시 실행해 MetalLB의 설정이 올바르게 적용 되었는지 확인
$ kubectl get configmap -n metallb-system -o yaml
8. 모든 설정이 완료됐으니 이제 각 디플로이먼트(lb-hname-pods,lb-ip-pods)를 로드밸런서 서비스로 노출
$ kubectl expose deployment/lb-hname-pods --type=LoadBalancer --name=lb-hname-svc --port=80
service/lb-hname-svc exposed
$ kubectl expose deployment/lb-ip-pods --type=LoadBalancer --name=lb-ip-svc --port=80
service/lb-ip-svc exposed
9. 생성된 로드밸런서 서비스별로 CLUSTER-IP와 EXTERNAL-IP가 잘 적용되었는지 확인하자. 특히 EXTERNAL-IP에 ConfigMap을 통해 부여한 IP를 확인
$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d2h <none>
lb-hname-svc LoadBalancer 10.97.197.98 192.168.1.11 80:32457/TCP 89s app=lb-hname-pods
lb-ip-svc LoadBalancer 10.103.52.73 192.168.1.12 80:30480/TCP 63s app=lb-ip-pods
10. 로컬 PC에서 웹 브라우저 접속 OR 터미널 창에서 curl로 테스트
# 192.168.1.12를 접속해 파드에 요청 방법과 IP가 표시되는지 확인
$ curl -X GET 192.168.1.12
request_method : GET | ip_dest: 172.16.103.146
다음 실습을 위해 배포한 Deployment와 서비스는 삭제하자.
kubectl delete deployment/lb-hname-pods
kubectl delete deployment/lb-ip-pods
kubectl delete svc/lb-hname-svc
kubectl delete svc/lb-ip-svc